Skip to content

Prove termination of diff algorithm implementation - #37

Draft
ninioArtillero wants to merge 19 commits into
seereason:masterfrom
tweag:xg/ses-termination
Draft

Prove termination of diff algorithm implementation#37
ninioArtillero wants to merge 19 commits into
seereason:masterfrom
tweag:xg/ses-termination

Conversation

@ninioArtillero

Copy link
Copy Markdown
Collaborator

All commits build independenlty and can be read in sequence.

The manhattan distance from a node towards the algorithm's end point (lena, lenb)
is used as termination metric for `addsnake`. Phantom parameters for both
input lengths are introduced to provide them as arguments to the metric.

The diagonal predicate `DiagPred` is a refinement type alias encoding the
condition of an equality predicate (such as `canDiag`) to enter the recursive call
inside `addsnake`. This allows Liquid Haskell to know that both coordinates
are smaller than its corresponding input length, those fulfilling
`manhattanDistance` preconditions.

`dstep` is extended to provide the required phantom parameters and is
temporarily ignored because proving node coordinates in a wave front are
within bounds (`manhatanDistance` preconditions) requires discarting
out-of-bounds nodes. This is implemented as an optimization in a following commit.
A `_wfDistanceToGoal` function is defined to be used as termination metric
for `ses`. In this commit, `dstep` is specified and checked to reduce it
from input to output.

The wave front diagonal condition is changed to look at the head
of the node list instead of the diagonal edit distance parameter,
and its nodes are specified to be within bounds.
Indeed, now that wave fronts are trimmed down to be within bounds,
we can no longer guarantee that the first node's diagonal matches
the edit distance.

The `stepAndMerge` specification is strengthen to preserve this new variant of
wave front diagonal invariant: With the current optimization of `dstep`,
wave fronts don't necessarily grow, but the 2-step specing is preserved.
The implementation of `ses` changes from a `dropWhile` driven search for
the algorithm's end point in a lazy stream composed of all wave front nodes,
to the explicit recursion of a wave-front wise search for such end point.

This change was designed to allow a termination proof using Liquid Haskell:
by inspecting each wave front separately, instead of all concatenated together in an
infinite stream, we can define a wave front metric as its minimum distance to
the endpoint and show it is reduced by the recursive calls (to `dstep`).

Performance-wise, we get a small optimization of the benchmark of ~12%
Comment thread src/Data/Algorithm/Diff.hs Outdated
Comment thread src/Data/Algorithm/Diff.hs Outdated
Comment thread src/Data/Algorithm/Diff.hs Outdated
Comment thread src/Data/Algorithm/Diff.hs Outdated
Comment thread src/Data/Algorithm/Diff/Refinement.hs Outdated
Comment thread src/Data/Algorithm/Diff.hs Outdated
Comment thread src/Data/Algorithm/Diff.hs Outdated
Comment thread src/Data/Algorithm/Diff.hs Outdated
Comment thread src/Data/Algorithm/Diff.hs
Comment thread src/Data/Algorithm/Diff.hs Outdated
@facundominguez

Copy link
Copy Markdown
Contributor

This PR should revert 33bf8bc, which is made redundant by a0f181c.

Comment thread src/Data/Algorithm/Diff.hs Outdated
facundominguez and others added 5 commits August 5, 2026 10:05
…eason#28)

The optimization introduced in `dstep` (narrowing the wave front to only
within bound nodes) solves the problem this additional equations addressed
in seereason@33bf8bc
They are removed to avoid unnecessary complexity.
Comment thread src/Data/Algorithm/Diff.hs Outdated
Comment thread src/Data/Algorithm/Diff.hs
Co-authored-by: Facundo Domínguez <facundominguez@gmail.com>
facundominguez and others added 4 commits August 6, 2026 15:52
The introduced benchmark makes the improvement of the `dstep`
refactoring (dropping out-of-bounds nodes) more noticeable.
A definition less, plus upstream has an optimization for `const`
in ucsd-progsys/liquidhaskell#2732
that could turn out to be useful (currently is makes no
difference because lemmas are not being composed).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants